#!/usr/bin/env python3
# -*- coding: utf-8 -*-



import subprocess
import time
import re
import csv
import os
import shutil
import platform
from datetime import datetime

# 根据操作系统选择适当的库
if platform.system() == 'Windows':
    try:
        import wexpect

        # 创建一个别名，使代码兼容
        pexpect = wexpect
        IS_WINDOWS = True
        # Windows系统下，增加调试输出
        DEBUG_MODE = True


        # wexpect库没有exceptions模块，需要自定义异常处理
        class WexpectExceptionWrapper:
            class ExceptionPexpect(Exception):
                pass


        pexpect.exceptions = WexpectExceptionWrapper
    except ImportError:
        print("错误: 在Windows系统上需要安装wexpect库。")
        print("请运行: pip install wexpect")
        exit(1)
else:
    import pexpect

    IS_WINDOWS = False
    DEBUG_MODE = False

#################################################
################ 配置参数区域 ####################
#################################################

# 设备类型选择
# "device1": 需要密码验证的设备 (默认)
# "device2": 只需账号不需密码的设备 (执行adb root后连接)
DEVICE_TYPE = "device2"

# 设备1配置 (需要密码验证)
DEVICE1_QNX_IP = "192.168.8.1"
DEVICE1_USERNAME = "root"
DEVICE1_PASSWORD = "sv2655888"

# 设备2配置 (只需账号无需密码)
DEVICE2_QNX_IP = "172.31.207.204"
DEVICE2_USERNAME = "root"

# ADB路径设置
# 如果为空，将自动查找adb路径；否则使用指定的路径
# 例如: "/Users/username/Library/Android/sdk/platform-tools/adb"
ADB_PATH = ""

# 设备序列号设置
# 如果设置为空，则使用默认设备；否则使用指定的设备
DEVICE_SERIAL = ""


#################################################
################ 程序代码区域 ####################
#################################################

def find_adb_path():
    """
    查找adb命令的路径

    Returns:
        adb命令的完整路径，如果未找到则返回None
    """
    # 首先检查是否已经设置了ADB_PATH
    if ADB_PATH and os.path.exists(ADB_PATH) and os.access(ADB_PATH, os.X_OK):
        return ADB_PATH

    # 检查环境变量中的adb
    adb_from_path = shutil.which('adb')
    if adb_from_path:
        return adb_from_path

    # 检查常见的adb安装路径
    common_paths = [
        # macOS 常见路径
        '/usr/local/bin/adb',
        os.path.expanduser('~/Library/Android/sdk/platform-tools/adb'),
        '/Applications/Android Studio.app/Contents/sdk/platform-tools/adb',
        # Linux 常见路径
        '/usr/bin/adb',
        '/opt/android-sdk/platform-tools/adb',
        # Windows 常见路径
        'C:\\Program Files\\Android\\sdk\\platform-tools\\adb.exe',
        'C:\\Program Files (x86)\\Android\\sdk\\platform-tools\\adb.exe',
        # 用户自定义安装路径
        os.path.expanduser('~/android-sdk/platform-tools/adb'),
        os.path.expanduser('~/Android/Sdk/platform-tools/adb')
    ]

    for path in common_paths:
        if os.path.exists(path) and os.access(path, os.X_OK):
            return path

    return None


class QNXConnect:
    def __init__(self,device_type=DEVICE_TYPE,
                 ip1=DEVICE1_QNX_IP, username1=DEVICE1_USERNAME, password1=DEVICE1_PASSWORD,
                 ip2=DEVICE2_QNX_IP, username2=DEVICE2_USERNAME, adb_path=None, device_serial=DEVICE_SERIAL):

        self.device_type = device_type
        self.ip1 = ip1
        self.username1 = username1
        self.password1 = password1
        self.ip2 = ip2
        self.username2 = username2
        # 如果没有提供adb_path，自动查找
        self.adb_path = adb_path if adb_path is not None else find_adb_path()
        # 设备序列号
        self.device_serial = device_serial

    def _get_adb_command(self, command):
        """根据是否指定设备序列号返回相应的adb命令"""
        if self.device_serial:
            return f'{self.adb_path} -s {self.device_serial} {command}'
        else:
            return f'{self.adb_path} {command}'

    def connect_to_qnx_device1(self):
        """连接到需要密码验证的QNX系统并返回终端会话"""
        # 确保adb路径有效
        if not self.adb_path:
            raise ValueError("无法找到adb命令。请确保已安装adb并添加到PATH环境变量中，或在脚本中设置ADB_PATH。")

        # 启动ADB shell
        adb_shell_cmd = self._get_adb_command('shell')
        print(f"使用adb命令: {adb_shell_cmd}")
        try:
            if DEBUG_MODE:
                print(f"DEBUG: 尝试启动adb shell: {adb_shell_cmd}")
            adb_shell = pexpect.spawn(adb_shell_cmd, timeout=15)
            if DEBUG_MODE:
                print("DEBUG: adb shell已启动")
        except Exception as e:
            if IS_WINDOWS:
                error_msg = f"启动adb shell失败: {str(e)}。请检查adb是否正确安装，设备是否连接。"
            else:
                error_msg = f"启动adb shell失败: {str(e)}。请检查adb是否正确安装，设备是否连接。"
            if DEBUG_MODE:
                print(f"DEBUG: {error_msg}")
            raise RuntimeError(error_msg)

        if DEBUG_MODE:
            print("DEBUG: 等待adb shell提示符...")
        index = adb_shell.expect(['#', '>', pexpect.TIMEOUT, pexpect.EOF], timeout=15)
        if index == 2:
            if DEBUG_MODE:
                print("DEBUG: adb shell连接超时")
            raise TimeoutError("adb shell连接超时。请检查设备是否已连接并开启USB调试。")
        elif index == 3:
            if DEBUG_MODE:
                print("DEBUG: adb shell连接失败")
            raise ConnectionError("adb shell连接失败。请检查设备是否已连接并开启USB调试。")

        if DEBUG_MODE:
            print(f"DEBUG: adb shell已连接，提示符索引: {index}")

        # 启动telnet连接
        print(f"连接到QNX系统 {self.ip1}...")
        if DEBUG_MODE:
            print(f"DEBUG: 发送命令: busybox telnet {self.ip1}")
        adb_shell.sendline(f'busybox telnet {self.ip1}')

        # 等待登录提示
        if DEBUG_MODE:
            print("DEBUG: 等待telnet登录提示...")
        index = adb_shell.expect(['login:', 'Connection refused', pexpect.TIMEOUT], timeout=15)
        if index == 1:
            if DEBUG_MODE:
                print("DEBUG: telnet连接被拒绝")
            raise ConnectionError(f"telnet连接被拒绝。请检查IP地址 {self.ip1} 和网络连接。")
        elif index == 2:
            if DEBUG_MODE:
                print("DEBUG: telnet连接超时")
            raise TimeoutError(f"telnet连接超时。请检查设备 {self.ip1} 是否可达。")

        if DEBUG_MODE:
            print("DEBUG: 收到登录提示")

        # 登录
        print(f"使用用户名 {self.username1} 登录...")
        adb_shell.sendline(self.username1)
        if DEBUG_MODE:
            print("DEBUG: 等待密码提示...")
        adb_shell.expect('Password:', timeout=15)
        if DEBUG_MODE:
            print("DEBUG: 收到密码提示，发送密码...")
        adb_shell.sendline(self.password1)

        # 确认登录成功
        if DEBUG_MODE:
            print("DEBUG: 等待登录确认...")
        index = adb_shell.expect(['#', '>', 'Login incorrect', pexpect.TIMEOUT], timeout=10)
        if index == 2:
            if DEBUG_MODE:
                print("DEBUG: 登录失败")
            raise ValueError("登录失败。请检查用户名和密码。")
        elif index == 3:
            if DEBUG_MODE:
                print("DEBUG: 登录超时")
            raise TimeoutError("登录后无响应。请检查设备状态。")

        if DEBUG_MODE:
            print(f"DEBUG: 登录成功，提示符索引: {index}")

        print("成功连接到QNX系统")
        return adb_shell

    def connect_to_qnx_device2(self):
        """连接到只需账号不需密码的QNX系统并返回终端会话"""
        # 确保adb路径有效
        if not self.adb_path:
            raise ValueError("无法找到adb命令。请确保已安装adb并添加到PATH环境变量中，或在脚本中设置ADB_PATH。")

        # 首先执行adb root
        print(f"执行adb root...")
        try:
            adb_root_cmd = self._get_adb_command('root')
            if DEBUG_MODE:
                print(f"DEBUG: 尝试执行adb root: {adb_root_cmd}")
            root_process = pexpect.spawn(adb_root_cmd, timeout=10)
            root_process.expect([pexpect.EOF, pexpect.TIMEOUT], timeout=10)
            root_process.close()
            # 给设备一些时间重启adbd
            if DEBUG_MODE:
                print("DEBUG: adb root执行完成，等待设备重启adbd...")
            time.sleep(3)
        except Exception as e:
            if DEBUG_MODE:
                print(f"DEBUG: adb root执行失败: {str(e)}")
            raise RuntimeError(f"执行adb root失败: {str(e)}。请检查设备是否支持root访问。")

        # 启动ADB shell
        print(f"启动adb shell...")
        try:
            adb_shell_cmd = self._get_adb_command('shell')
            if DEBUG_MODE:
                print(f"DEBUG: 尝试启动adb shell: {adb_shell_cmd}")
            adb_shell = pexpect.spawn(adb_shell_cmd, timeout=15)
            if DEBUG_MODE:
                print("DEBUG: adb shell已启动")
        except Exception as e:
            if DEBUG_MODE:
                print(f"DEBUG: adb shell启动失败: {str(e)}")
            raise RuntimeError(f"启动adb shell失败: {str(e)}。请检查adb是否正确安装，设备是否连接。")

        if DEBUG_MODE:
            print("DEBUG: 等待adb shell提示符...")
        index = adb_shell.expect(['#', '>', pexpect.TIMEOUT, pexpect.EOF], timeout=15)
        if index == 2:
            if DEBUG_MODE:
                print("DEBUG: adb shell连接超时")
            raise TimeoutError("adb shell连接超时。请检查设备是否已连接并开启USB调试。")
        elif index == 3:
            if DEBUG_MODE:
                print("DEBUG: adb shell连接失败")
            raise ConnectionError("adb shell连接失败。请检查设备是否已连接并开启USB调试。")

        if DEBUG_MODE:
            print(f"DEBUG: adb shell已连接，提示符索引: {index}")

        # 启动telnet连接
        print(f"连接到QNX系统 {self.ip2}...")
        if DEBUG_MODE:
            print(f"DEBUG: 发送命令: busybox telnet {self.ip2}")
        adb_shell.sendline(f'busybox telnet {self.ip2}')

        # 等待登录提示
        if DEBUG_MODE:
            print("DEBUG: 等待telnet登录提示...")
        index = adb_shell.expect(['login:', 'Connection refused', pexpect.TIMEOUT], timeout=15)
        if index == 1:
            if DEBUG_MODE:
                print("DEBUG: telnet连接被拒绝")
            raise ConnectionError(f"telnet连接被拒绝。请检查IP地址 {self.ip2} 和网络连接。")
        elif index == 2:
            if DEBUG_MODE:
                print("DEBUG: telnet连接超时")
            raise TimeoutError(f"telnet连接超时。请检查设备 {self.ip2} 是否可达。")

        if DEBUG_MODE:
            print("DEBUG: 收到登录提示")

        # 登录(只需要用户名，不需要密码)
        print(f"使用用户名 {self.username2} 登录...")
        adb_shell.sendline(self.username2)

        # 确认登录成功，这里不会提示输入密码
        if DEBUG_MODE:
            print("DEBUG: 等待登录确认...")
        index = adb_shell.expect(['#', '>', 'Login incorrect', pexpect.TIMEOUT], timeout=10)
        if index == 2:
            if DEBUG_MODE:
                print("DEBUG: 登录失败")
            raise ValueError("登录失败。请检查用户名。")
        elif index == 3:
            if DEBUG_MODE:
                print("DEBUG: 登录超时")
            raise TimeoutError("登录后无响应。请检查设备状态。")

        if DEBUG_MODE:
            print(f"DEBUG: 登录成功，提示符索引: {index}")

        print("成功连接到QNX系统")
        return adb_shell

    def connect_to_qnx(self):
        """根据设备类型选择适当的连接方法"""
        if self.device_type == "device1":
            return self.connect_to_qnx_device1()
        elif self.device_type == "device2":
            return self.connect_to_qnx_device2()
        else:
            raise ValueError(f"不支持的设备类型: {self.device_type}。请使用 'device1' 或 'device2'。")

    def run_adb_command(self, command):
        """运行adb命令并返回结果"""
        full_command = self._get_adb_command(command)
        print(f"执行命令: {full_command}")
        result = subprocess.run(full_command, shell=True, capture_output=True, text=True)
        if result.returncode != 0:
            print(f"错误: {result.stderr}")
        return result








if __name__ == '__main__':
    pass